let str: string; //字符串类型
let any: any; //任意类型
let un: undefined; //undefined类型
let nul: null; //null类型
let neve: never; //其他类型   基本不会用到
 

// 数组
let attr: number[]; //数组类型
let attr2: Array<number>; //数组类型


// 元组类型  属于数组的一种
let attr3: [number, string] = [2, "222"];




// 枚举类型     多数用于表示状态码，颜色， 以及一些状态信息什么的
enum Flag {
    success = 1,
    errow = 2
};
let s: Flag = Flag.success
console.log(s) //1


enum Color {
    red,
    blue,
    green
}
let c: Color = Color.red

console.log(c) //0   如果标识符没有复制那么打印的是下标 


//任意类型用法
let odiv: any = document.getElementById('div1')
odiv.style.color = 'red'


// 函数的定义


// 方法
function fn1(): void {

}
// 参数加问好代表可传可不传
function fn2(num1: number, num2?: number): void {

}
// ts函数重载


function getInfo(name: string): string;

function getInfo(age: number): number;

function getInfo(age: any): any {
    if (typeof str === 'string') {
        return '我叫' + name
    } else {
        return '我的年龄是' + age
    }
}

console.log(getInfo(22))


// typescript 中的类

class Preson {
    private name: string;
    constructor(name: string) { //构造函数   实例化类的时候触发的方法
        this.name = name
    }

    run(): void {
        console.log(this.name)
    }
}

class Web extends Preson {

    constructor(name: string) { //构造函数   实例化类的时候触发的方法
        super(name)

    }
}

var w = new Preson('wwwww');



// public 公有  在类里 ，子类， 类外面都可以访问

// protected 保护类型 在类里面，子类里面可以访问，在类未免不能用
// private  私有的在类里可以访问  在子类以及外部无法访问



// 接口 属性接口     对json的约束

// 就是传入对象的约束    属性接口
interface FullName {
    label: string;              //注意以分号结束
    options?: Array<Object>;    //加上问好代表参数是可选的
}

function printLable(data: FullName): void {

}
var obj = {
    label: '',
    name: 20
}
printLable(obj)


// 函数类型接口
interface encrypt {
    (key: string, value: string): string;
}

var md5: encrypt = (key: string, value: string): string => {
    return 'aa'
}

// 可索引接口：数组对象的约束 (不常用)

interface UserArr {
    [index: number]: string
}
var arr: UserArr = ["222"]


// 类类型接口：对类的约束  和抽象类有点相似

interface Anima {
    name: string;
    eat?(key: string, value: string): string;

}

class Dog implements Anima {         //实现接口
    name: string;
    constructor(name: string) {
        this.name = name
    }
    // eat(key: string, value: string){
    //     return '22222'
    // }
}


// 接口扩展：接口可以继承接口
interface Qwe {
    eat(): void;
}
interface person extends Qwe {
    
}


// 泛型 可以支持不特定的数据类型  要求：传入的参数和返回的参数一致

// 通俗理解：泛型就是解决 类接口 方法的复用性，以及对不特定数据类型 的支持
// T表示泛型，具体什么类型是调用这个方法时候决定的
function getData<T>(value: T) {
    return value
}
getData<number>(123)
// getData<number>('123')  //错


// 类的泛型
class MinClas<T>{
    add(value: T): void {
        console.log('asdasd')
    }
}

var m1 = new MinClas<number>();     //传入 泛型
m1.add(5)
  

// 泛型接口 
interface ConfigFn {
    <T>(value: T): T;
}
var setData: ConfigFn = function <T>(value: T): T {
    return value;
}  
setData<number>(1)      